//
// Created by lingzhitech on 25-11-5.
//

#include "StrBlobPtr.hpp"

std::shared_ptr<std::vector<std::string> >
StrBlobPtr::check(std::size_t i, const std::string &message) const {
    auto ret = wptr.lock();
    if (!ret) {
        throw std::runtime_error("unbound StrBlobPtr");
    }
    if (i >= ret->size()) {
        throw std::out_of_range(message);
    }
    return ret;
}

StrBlobPtr & StrBlobPtr::operator++() {
    check(current_position, "StrBlobPtr::operator++()");
    ++current_position;
    return *this;
}

StrBlobPtr & StrBlobPtr::operator--() {
    --current_position;
    check(current_position, "StrBlobPtr::operator--()");
    return *this;
}

StrBlobPtr StrBlobPtr::operator++(int) {
    StrBlobPtr ret = *this;
    ++*this;
    return ret;
}

StrBlobPtr StrBlobPtr::operator--(int) {
    StrBlobPtr ret = *this;
    --*this;
    return ret;
}

std::string & StrBlobPtr::operator*() const {
    auto p = check(current_position, "StrBlobPtr::operator*()");
    return (*p)[current_position];
}

std::string * StrBlobPtr::operator->() const {
    return & (this->operator*());
}

std::string& StrBlobPtr::deref() const {
    auto p = check(current_position, "dereference past end");
    return (*p)[current_position];
}

StrBlobPtr& StrBlobPtr::incr() {
    check(current_position, "increment past end of StrBlobStr");
    ++current_position;
    return *this;
}

bool operator==(const StrBlobPtr &lhs, const StrBlobPtr &rhs) {
    return lhs.current_position == rhs.current_position &&
        lhs.wptr.lock() == rhs.wptr.lock();
}

bool operator!=(const StrBlobPtr &lhs, const StrBlobPtr &rhs) {
    return !(lhs == rhs);
}